#pragma once

#include <common/BlockingQueue.h>
#include <common/EventBase.h>
#include <common/Network.h>
#include <common/Pipeline.h>
#include <common/DataPlaneUpdate.h>
#include <folly/MPMCPipeline.h>

#include <thread>
#include <vector>

namespace flashpp {

class Flashpp {
 public:
  Flashpp(Network& network);
  ~Flashpp();

  void run();
  void push(std::shared_ptr<DataPlaneUpdate> dpu);

 private:
  /**
   * Start an EventBase in a thread, maintain order of thread creation and
   * returns raw pointer of Derived class.
   */
  template <typename T>
  T* startEventBase(
      std::vector<std::thread>& allThreads,
      std::vector<std::unique_ptr<EventBase>>& orderedEvbs,
      const std::string& name,
      std::unique_ptr<T> evbT);

  // BlockingQueue<Rule>& bqueue;
  Pipeline pipeline;
  std::vector<std::thread> allThreads;
  std::vector<std::unique_ptr<EventBase>> orderedEvbs;

  Network& network_;
};

} // namespace flashpp